package org.springframework.security.oauth2.provider;

import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.common.util.OAuth2Utils;
import org.springframework.web.bind.annotation.SessionAttributes;

@SuppressWarnings("serial")
@Deprecated
public class AuthorizationRequest extends BaseRequest implements Serializable {

    private Map<String, String> approvalParameters = Collections.unmodifiableMap(new HashMap<String, String>());

    private String state;

    private Set<String> responseTypes = new HashSet<String>();

    private Set<String> resourceIds = new HashSet<String>();

    private Collection<? extends GrantedAuthority> authorities = new HashSet<GrantedAuthority>();

    private boolean approved = false;

    private String redirectUri;

    private Map<String, Serializable> extensions = new HashMap<String, Serializable>();

    public AuthorizationRequest() {
    }

    public AuthorizationRequest(Map<String, String> authorizationParameters, Map<String, String> approvalParameters, String clientId, Set<String> scope, Set<String> resourceIds, Collection<? extends GrantedAuthority> authorities, boolean approved, String state, String redirectUri, Set<String> responseTypes) {
        setClientId(clientId);
        setRequestParameters(authorizationParameters); // in case we need to
        // wrap the collection
        setScope(scope); // in case we need to parse
        if (resourceIds != null) {
            this.resourceIds = new HashSet<String>(resourceIds);
        }
        if (authorities != null) {
            this.authorities = new HashSet<GrantedAuthority>(authorities);
        }
        this.approved = approved;
        this.resourceIds = resourceIds;
        this.redirectUri = redirectUri;
        if (responseTypes != null) {
            this.responseTypes = responseTypes;
        }
        this.state = state;
    }

    public OAuth2Request createOAuth2Request() {
        return new OAuth2Request(getRequestParameters(), getClientId(), getAuthorities(), isApproved(), getScope(), getResourceIds(), getRedirectUri(), getResponseTypes(), getExtensions());
    }

    public AuthorizationRequest(String clientId, Collection<String> scopes) {
        setClientId(clientId);
        setScope(scopes); // in case we need to parse
    }

    public void setResourceIdsAndAuthoritiesFromClientDetails(ClientDetails clientDetails) {
        setResourceIds(clientDetails.getResourceIds());
        setAuthorities(clientDetails.getAuthorities());
    }

    public Map<String, String> getApprovalParameters() {
        return approvalParameters;
    }

    public void setApprovalParameters(Map<String, String> approvalParameters) {
        this.approvalParameters = approvalParameters;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public Set<String> getResponseTypes() {
        return responseTypes;
    }

    public void setResponseTypes(Set<String> responseTypes) {
        this.responseTypes = responseTypes;
    }

    public void setRedirectUri(String redirectUri) {
        this.redirectUri = redirectUri;
    }

    public void setApproved(boolean approved) {
        this.approved = approved;
    }

    public void setAuthorities(Collection<? extends GrantedAuthority> authorities) {
        if (authorities != null) {
            this.authorities = new HashSet<GrantedAuthority>(authorities);
        }
    }

    public Map<String, Serializable> getExtensions() {
        return extensions;
    }

    public void setExtensions(Map<String, Serializable> extensions) {
        this.extensions = extensions;
    }

    public void setResourceIds(Set<String> resourceIds) {
        this.resourceIds = resourceIds;
    }

    public void setClientId(String clientId) {
        super.setClientId(clientId);
    }

    public void setScope(Collection<String> scope) {
        super.setScope(scope);
    }

    public void setRequestParameters(Map<String, String> requestParameters) {
        super.setRequestParameters(requestParameters);
    }

    public Set<String> getResourceIds() {
        return resourceIds;
    }

    public Collection<? extends GrantedAuthority> getAuthorities() {
        return authorities;
    }

    public boolean isApproved() {
        return approved;
    }

    public String getRedirectUri() {
        return redirectUri;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = super.hashCode();
        result = prime * result + ((approvalParameters == null) ? 0 : approvalParameters.hashCode());
        result = prime * result + ((responseTypes == null) ? 0 : responseTypes.hashCode());
        result = prime * result + ((state == null) ? 0 : state.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (!super.equals(obj))
            return false;
        if (getClass() != obj.getClass())
            return false;
        AuthorizationRequest other = (AuthorizationRequest) obj;
        if (approvalParameters == null) {
            if (other.approvalParameters != null)
                return false;
        } else if (!approvalParameters.equals(other.approvalParameters))
            return false;
        if (responseTypes == null) {
            if (other.responseTypes != null)
                return false;
        } else if (!responseTypes.equals(other.responseTypes))
            return false;
        if (state == null) {
            if (other.state != null)
                return false;
        } else if (!state.equals(other.state))
            return false;
        return true;
    }
}